#include "dtwentycore.h"
#include "skill.h"
#include "skillsynergy.h"
#include "specialability.h"
#include "characterclass.h"


#include "dtwentyitemsmodel.h"


#include <itemtablemodel.h>
#include <xmlserializer.h>


#include <QDebug>
#include <QBuffer>
#include <QFile>

DTwentyCore::DTwentyCore(QObject *parent) :
    QObject(parent),
    m_skills(new DTwentyItemsModel(Skill::staticMetaObject, this)),
    m_specialAbilities(new DTwentyItemsModel(SpecialAbility::staticMetaObject, this)),
    m_characterClasses(new DTwentyItemsModel(CharacterClass::staticMetaObject, this))
{
    qRegisterMetaType<Campaign*>();
    qRegisterMetaType<DTwentyItemsModel*>();

    m_skills->setSourceModel(new ItemTableModel(this));
    m_specialAbilities->setSourceModel(new ItemTableModel(this));
    m_characterClasses->setSourceModel(new ItemTableModel(this));

//    qDebug() << Q_FUNC_INFO << "Skills role names:" << m_skills->roleNames().values();
}

void DTwentyCore::createCampaign()
{
    /// \todo Put campaign template to resources!
    /// \author Jussi
    /// \date 2013-10-29

    m_campaign = new Campaign(this);

    // test skills
    Skills* skills = new Skills(m_campaign);
    Skill* skill1 = skills->createItem("Do Something");
    skill1->setKeyAbility(2);
    skill1->setArmorCheckPenalty(true);
    skill1->setUseUntrained(true);

    Skill* skill2 = skills->createItem("Do More (Of These)");
    skill2->setKeyAbility(1);
    skill2->setTryAgain(true);
    skill2->setAction(2);
    skill2->setCheck("Description 2");
    skill2->setRestrictions("None");
    skill2->addSkillSynergy(skill1);


    // test special abilities
    SpecialAbilities* specials = new SpecialAbilities(m_campaign);
//    m_specialAbilities->setRoot(specials);
    SpecialAbility* special1 = specials->createItem("Very Special");
    special1->setMultiple(1);

    SpecialAbility* special2 = specials->createItem("Extraordinary Special");
    special2->setType(2);


    // test character classes

    CharacterClasses* classes = new CharacterClasses(m_campaign);
//    m_characterClasses->setRoot(classes);
    CharacterClass* class1 = classes->createItem("Powerful Class");
    class1->setHitDie(1);
    class1->setSkillPoints(3);
    class1->setBaseAttack(1);
    class1->setRefSave(1);

    CharacterClass* class2 = classes->createItem("Munchin Class");
    class2->setSkillPoints(2);
    class2->setWillSave(1);

    // test class skills
    class1->addClassSkill(skill1);
    class1->addClassSkill(skill1);

    class2->addClassSkill(skill1);
    class2->addClassSkill(skill2);

    // test special ability setting
    special1->addCharacterLevel(class1, 1);
    special1->addCharacterLevel(class1, 5);
    special1->addCharacterLevel(class2, 2);

    special2->addCharacterLevel(class2, 6);
    special2->addCharacterLevel(class2, 8); // should fail
    special2->addCharacterLevel(class1, 4);


    // set model root items
    setRootFor(m_skills, skills);
    setRootFor(m_specialAbilities, specials);
    setRootFor(m_characterClasses, classes);

    // test serialization and deserialization

    m_campaign->dumpObjectTree();

    qDebug() << "*************************";


    QBuffer writeBuf;
    if (!writeBuf.open(QBuffer::ReadWrite))
    {
        qDebug() << "Failed to open write buffer";
        return;
    }

    XmlSerializer ser;
    ser.serialize(m_campaign, &writeBuf);

    if (!writeBuf.size())
    {
        qDebug() << "Write buffer is empty";
        return;
    }

    QFile file("test.xml");
    if (file.open(QFile::WriteOnly))
    {
       ser.serialize(m_campaign, &file);
    }
    qDebug() << writeBuf.data();
    qDebug() << "*************************";

    QBuffer readBuf;
    readBuf.setData(writeBuf.data());
    if (!readBuf.open(QBuffer::ReadWrite))
    {
        qDebug() << "Failed to open read buffer";
        return;
    }

    m_campaign = qobject_cast<Campaign*>(ser.deserialize(&readBuf));
    if (m_campaign.isNull())
    {
        qDebug() << "Deserializing read buffer failed";
        return;
    }

    m_campaign->dumpObjectTree();

    qDebug() << "*************************";
    qDebug() << ".... DONE ....";




}

DTwentyItemsModel *DTwentyCore::skillsModel() const
{
    return m_skills;
}

DTwentyItemsModel *DTwentyCore::specialAbilitiesModel() const
{
    return m_specialAbilities;
}

DTwentyItemsModel *DTwentyCore::characterClassesModel() const
{
    return m_characterClasses;
}

void DTwentyCore::setSkillsModel(DTwentyItemsModel *arg)
{

}

void DTwentyCore::setSpecialAbilitiesModel(DTwentyItemsModel *arg)
{

}

void DTwentyCore::setCharacterClassesModel(DTwentyItemsModel *arg)
{

}

void DTwentyCore::setRootFor(QAbstractProxyModel *proxyModel, ModelItem *root)
{
    ItemTreeModel* model = qobject_cast<ItemTreeModel*>(proxyModel->sourceModel());
    if (!model)
    {
        return;
    }

    model->setRoot(root);
}


